package com.star.util.xml;

import java.io.BufferedWriter;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.io.FileUtils;
import org.dom4j.Attribute;
/**dom4j-1.6.1.jar*/
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;
import org.springframework.util.StringUtils;

/**
 *
 * <p>
 * Title: XML 处理关(通过dom4j-1.6.1.jar 解析XML)
 * </p>
 *
 * <p>
 * Description:
 * </p>
 *
 * <p>
 * Copyright: Copyright (c) 2009-07
 * </p>
 *
 * <p>
 * Company: 京泰信息
 * </p>
 *
 * @author bzq
 * @version 1.0
 */

public class XmlDomParse {

	/**
	 * 按节点名，取其值 如取send值"/smil/type/send"
	 * <smil><type><ip>127.0.0.1</ip><send>MmsManagerForSingle
	 * </send></type></smil>
	 * 
	 * @param xmlSource
	 *            String
	 * @param elementName
	 *            String
	 * @return String
	 */
	public String getElementTitle(String xmlSource, String elementName) {
		String elementValue = "";
		try {
			SAXReader saxReader = new SAXReader();
			Document document = saxReader.read(new ByteArrayInputStream(
					xmlSource.getBytes()));
			Element root = document.getRootElement(); // 获得根节点
			// 得到database节点
			Element database = (Element) root.selectSingleNode(elementName);
			if (database != null) {
				return database.getText();
			} else {
				return null;
			}
		} catch (Exception exe) {
			exe.printStackTrace();
		}
		return elementValue;
	}

	/**
	 * 查询元素节点 如取send值"/smil/type/send"
	 * <smil><type><ip>127.0.0.1</ip><send>MmsManagerForSingle
	 * </send></type></smil>
	 * 
	 * @param xmlSource
	 *            String
	 * @param elementName
	 *            String
	 * @return boolean
	 */
	public boolean selectElement(String xmlSource, String elementName) {
		if (!StringUtils.hasText(xmlSource)) {
			return false;
		}
		try {
			xmlSource = xmlSource.replaceAll(">>", ">");
			SAXReader saxReader = new SAXReader();
			Document document = saxReader.read(new ByteArrayInputStream(
					xmlSource.getBytes()));
			Element root = document.getRootElement(); // 获得根节点
			// 得到database节点
			Element database = (Element) root.selectSingleNode(elementName);
			if (database != null) {
				return true;
			} else {
				return false;
			}
		} catch (Exception exe) {
			exe.printStackTrace();
			return false;
		}
	}

	public static void main(String[] args) {
		// XmlDomParse obj = new XmlDomParse();
		// obj.traversalDocumentByIterator("");
		long start = System.currentTimeMillis();
		String source = "<smil><type><ip>127.0.0.1</ip><send>MmsManagerForSingle</send></type></smil>";
		String elementName = "/smil/type/send";
		new XmlDomParse().getElementTitle(source, elementName);
		long end = System.currentTimeMillis();
		System.out.println((end - start) / 1000.0);
	}

	/**
	 * 这方法有问题
	 * 
	 * 按节点名，取节点属性值 如取send值"/smil/type/send"
	 * <smil><type><ip>127.0.0.1</ip><send>MmsManagerForSingle
	 * </send></type></smil>
	 * 
	 * @param xmlSource
	 *            String
	 * @param elementName
	 *            String
	 * @return String
	 */
	public String getElementProperty(String xmlSource, String elementName) {
		String elementPropertyValue = "";
		try {
			SAXReader saxReader = new SAXReader();
			Document document = saxReader.read(new ByteArrayInputStream(
					xmlSource.getBytes()));
			Element root = document.getRootElement(); // 获得根节点
			// 得到database节点
			List list = (List) root.selectNodes(elementName);
			Iterator iter = list.iterator();
			if (iter.hasNext()) {
				Attribute attribute = (Attribute) iter.next();
				// hm.put("崔卫兵-" + attribute.getName(), attribute.getValue());
				elementPropertyValue = attribute.getValue();
			}
		} catch (Exception exe) {
			exe.printStackTrace();
		}
		return elementPropertyValue;
	}

	public String getEP(String xmlSource, String elementName) {
		String elementPropertyValue = "";
		try {
			SAXReader saxReader = new SAXReader();
			Document document = saxReader.read(new ByteArrayInputStream(
					xmlSource.getBytes()));
			Element root = document.getRootElement(); // 获得根节点
			// 得到database节点
			Element element = (Element) root.selectSingleNode(elementName);
			elementPropertyValue = element.attribute(0).getValue();
		} catch (Exception exe) {
			exe.printStackTrace();
		}
		return elementPropertyValue;
	}

	/**
	 * 修改XML属性 如取send值"/smil/type/send"
	 * <smil><type><ip>127.0.0.1</ip><send>MmsManagerForSingle
	 * </send></type></smil>
	 * 
	 * @param xmlSource
	 *            String
	 * @param elementName
	 *            String
	 * @param attributeValue
	 *            String
	 * @return String
	 */
	public String updataElementProperty(String xmlSource, String elementName,
			String attributeValue) {
		String elementPropertyValue = "";
		try {
			SAXReader saxReader = new SAXReader();
			Document document = saxReader.read(new ByteArrayInputStream(
					xmlSource.getBytes()));
			Element root = document.getRootElement(); // 获得根节点
			// 得到database节点
			List list = (List) root.selectNodes(elementName);

			Iterator iter = list.iterator();
			if (iter.hasNext()) {
				Attribute attribute = (Attribute) iter.next();
				attribute.setValue(attributeValue);
			}
			elementPropertyValue = document.asXML();
		} catch (Exception exe) {
			exe.printStackTrace();
		}
		return elementPropertyValue;
	}

	public String updataEP(String xmlSource, String elementName,
			String attributeValue) {
		String elementPropertyValue = "";
		try {
			SAXReader saxReader = new SAXReader();
			Document document = saxReader.read(new ByteArrayInputStream(
					xmlSource.getBytes()));
			Element root = document.getRootElement(); // 获得根节点
			// 得到database节点
			Element element = (Element) root.selectSingleNode(elementName);

			Attribute attribute = element.attribute(0);

			attribute.setValue(attributeValue);

			elementPropertyValue = document.asXML();
		} catch (Exception exe) {
			exe.printStackTrace();
		}
		return elementPropertyValue;
	}

	/**
	 * 通过正则表达式,按元素分割 XML 串 <send>MmsManagerForSingle</send>
	 * 
	 * @param sourceXml
	 *            String
	 * @param elementName
	 *            String
	 * @return String
	 */
	public String partitionXml(String sourceXml, String elementName) {
		String elementValue = "";
		Pattern pattern = Pattern.compile("<" + elementName + "(.*?\\n?)*?</"
				+ elementName + ">");
		Matcher matcher = pattern.matcher(sourceXml);
		StringBuffer buffer = new StringBuffer();
		while (matcher.find()) {
			buffer.append(matcher.group());
			buffer.append("\r\n");
			System.out.println("通过正则表达式,按元素分割 XML 串:" + buffer.toString());
			elementValue = buffer.toString();
		}
		return elementValue;
	}

	/**
	 * 分组 XML 串 按元素,通过正则表达式 <send>MmsManagerForSingle</send>
	 * 
	 * @param sourceXml
	 *            String
	 * @param elementName
	 *            String
	 * @return List
	 */
	public List partitionXmlMap(String sourceXml, String elementName) {
		List resultList = new ArrayList();
		String patternStr = "\\([^)]+\\)";
		Pattern pattern = Pattern.compile("<" + elementName + "([^)]+)</"
				+ elementName + ">");
		Matcher matcher = pattern.matcher(sourceXml);
		for (int j = 0; matcher.find(); j++) {

			StringBuffer buffer = new StringBuffer();
			buffer.append(matcher.group(j));
			String elementValue = buffer.toString();
			System.out.println("分组 XML 串 按元素,通过正则表达式:" + elementValue);
			resultList.add(elementValue);
		}
		return resultList;
	}

	/**
	 * 
	 * 替换内容,通过正则表达式 <send>MmsManagerForSingle</send>
	 * 
	 * @param sourceXml
	 *            String
	 * @param replaceValues
	 *            String
	 * @return List
	 */
	public String replaceXmlMap(String sourceXml, String replaceValues) {
		Pattern p = Pattern.compile("src=\"([^)]+)region",
				Pattern.CASE_INSENSITIVE);
		// 用Pattern类的matcher()方法生成一个Matcher对象
		Matcher m = p.matcher(sourceXml);
		StringBuffer sb = new StringBuffer();
		// 使用find()方法查找第一个匹配的对象
		boolean result = m.find();
		// 使用循环找出模式匹配的内容替换之,再将内容加到sb里
		while (result) {
			m.appendReplacement(sb, "src=\"" + replaceValues + "\" region");
			result = m.find();
		}
		// 最后调用appendTail()方法将最后一次匹配后的剩余字符串加到sb里；
		m.appendTail(sb);
		return sb.toString();
	}

	public void test() {
		String xml_temp2 = "<body><par dur=\"10s\"><text src=\"mms_296766310.txt\" region=\"text\"/></par></body>";
		String partitionXmlMap = this.replaceXmlMap(xml_temp2, "&&&&&");

		System.out.println("*****");
		System.out.println(partitionXmlMap);
		System.out.println("@@@@@");

	}

	public void traversalDocumentByIterator(String xmlSource) {
		try {
			xmlSource = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><body><par dur=\"10s\"><text src=\"mms_296766310.txt\" region=\"text\"/></par></body><body><par dur=\"10s\"><text src=\"mms_296766310.txt\" region=\"text\"/></par></body>";
			SAXReader saxReader = new SAXReader();
			Document document = saxReader.read(new ByteArrayInputStream(
					xmlSource.getBytes()));
			Element root = document.getRootElement(); // 获得根节点
			// 枚举根节点下所有子节点
			for (Iterator ie = root.elementIterator(); ie.hasNext();) {
				System.out.println("======");
				Element element = (Element) ie.next();
				System.out.println(element.getName());
				// 枚举属性
				for (Iterator ia = element.attributeIterator(); ia.hasNext();) {
					Attribute attribute = (Attribute) ia.next();
					System.out.println(attribute.getName() + ":"
							+ attribute.getData());
				}
				// 枚举当前节点下所有子节点
				for (Iterator ieson = element.elementIterator(); ieson
						.hasNext();) {
					Element elementSon = (Element) ieson.next();
					System.out.println(elementSon.getName() + ":"
							+ elementSon.getText());
				}
			}
		} catch (Exception exe) {
			exe.printStackTrace();
		}
	}

	/**
	 * 判断是否只有一个根节点
	 * 
	 * @Description: TODO
	 * @author starhq
	 * @createtime 2014年7月27日 下午2:20:13
	 * @email : jian.wang@shinsoft.net
	 * @edit @{todo}
	 * @edittime
	 * @version 1.0
	 * @copyright shinsoft
	 */
	public boolean needConvert(String xmlSource) {
		int i = -1;
		try {
			SAXReader saxReader = new SAXReader();
			Document document = saxReader.read(new ByteArrayInputStream(
					xmlSource.getBytes()));
			Element element = document.getRootElement();
			i = element.elements().size();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return i > 0 ? true : false;
	}

	/**
	 * 写入XML到文件
	 * 
	 * @param doc
	 *            XML文档
	 * @param filePath
	 *            文件的路径
	 * @param charset
	 *            字符集
	 * @param isEscapeText
	 *            是否对特殊字符转义
	 * @throws IOException
	 */
	public static void xmlWriteToFile(Document doc, String filePath,
			String charset, boolean isEscapeText) throws IOException {
		OutputFormat outputFormat = OutputFormat.createPrettyPrint();
		outputFormat.setEncoding(charset);
		XMLWriter writer = null;
		try {
			writer = new XMLWriter(new BufferedWriter(new OutputStreamWriter(
					FileUtils.openOutputStream(new File(filePath), false))),
					outputFormat);
			writer.setEscapeText(isEscapeText);
			writer.write(doc);
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} finally {
			if (writer != null)
				writer.close();
		}
	}
}
